home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / sound / sound premixer effect / componentdispatch.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  12.4 KB  |  306 lines

  1. /*
  2.     File:        ComponentDispatch.c
  3.  
  4.     Contains:    Common routines for dispatching for any sound component
  5.  
  6.     Written by: Mark Cookson    
  7.  
  8.     Copyright:    Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 8/20/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23. #include <Components.h>
  24. #include <Sound.h>
  25. #include "VU-Meter.h"
  26.  
  27. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  28. //    Sound Component Function Prototypes
  29.  
  30. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  31. // component stuff
  32.  
  33. static pascal ComponentResult __SoundComponentOpen(void *unused1, ComponentInstance self);
  34. static pascal ComponentResult __SoundComponentClose(SoundComponentGlobalsPtr globals, ComponentInstance self);
  35. static pascal ComponentResult __SoundComponentRegister(SoundComponentGlobalsPtr globals);
  36. static pascal ComponentResult __SoundComponentCanDo(void *unused1, short selector);
  37.  
  38. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  39. // basic stuff
  40.  
  41. static pascal ComponentResult __SoundComponentSetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance source);
  42. static pascal ComponentResult __SoundComponentGetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance *source);
  43. static pascal ComponentResult __SoundComponentGetSourceData(SoundComponentGlobalsPtr globals, SoundComponentDataPtr *sourceData);
  44. static pascal ComponentResult __SoundComponentSetOutput(SoundComponentGlobalsPtr globals, SoundComponentDataPtr requested, SoundComponentDataPtr *actual);
  45.  
  46. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  47. // info methods
  48.  
  49. static pascal ComponentResult __SoundComponentGetInfo(SoundComponentGlobalsPtr globals, SoundSource sourceID, OSType selector, void *infoPtr);
  50.  
  51. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  52. // control methods
  53.  
  54. static pascal ComponentResult __SoundComponentStopSource(SoundComponentGlobalsPtr globals, short count, SoundSource *sources);
  55. static pascal ComponentResult __SoundComponentPlaySourceBuffer(SoundComponentGlobalsPtr globals, SoundSource sourceID, SoundParamBlockPtr pb, long actions);
  56.  
  57.  
  58. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  59. // types
  60. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  61.  
  62. #if GENERATINGCFM
  63.  
  64. // These structs are use in PowerMac builds to cast the
  65. // ComponentParameters passed into our component's entry point.
  66.  
  67. enum {
  68.     uppSoundComponentEntryPointProcInfo = kPascalStackBased
  69.         | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  70.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ComponentParameters *)))
  71.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(void *)))
  72. };
  73.  
  74. // These are used to create the routine descriptor to call each function.
  75.  
  76. enum {
  77.         uppSoundComponentOpenProcInfo = kPascalStackBased
  78.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  79.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(void *)))
  80.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ComponentInstance)))
  81. };
  82.  
  83. enum {
  84.         uppSoundComponentCloseProcInfo = kPascalStackBased
  85.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  86.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  87.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ComponentInstance)))
  88. };
  89.  
  90. enum {
  91.         uppSoundComponentRegisterProcInfo = kPascalStackBased
  92.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  93.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  94. };
  95.  
  96. enum {
  97.         uppSoundComponentSetSourceProcInfo = kPascalStackBased
  98.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  99.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  100.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundSource)))
  101.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ComponentInstance)))
  102. };
  103.  
  104. enum {
  105.         uppSoundComponentGetSourceProcInfo = kPascalStackBased
  106.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  107.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  108.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundSource)))
  109.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ComponentInstance*)))
  110. };
  111.  
  112. enum {
  113.         uppSoundComponentGetSourceDataProcInfo = kPascalStackBased
  114.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  115.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  116.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundComponentDataPtr)))
  117. };
  118.  
  119. enum {
  120.         uppSoundComponentSetOutputProcInfo = kPascalStackBased
  121.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  122.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  123.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundComponentDataPtr)))
  124.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(SoundComponentDataPtr)))
  125. };
  126.  
  127. enum {
  128.         uppSoundComponentGetInfoProcInfo = kPascalStackBased
  129.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  130.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  131.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundSource)))
  132.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(OSType)))
  133.                 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void *)))
  134. };
  135.  
  136. enum {
  137.         uppSoundComponentStopSourceProcInfo = kPascalStackBased
  138.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  139.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  140.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short)))
  141.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(SoundSource)))
  142. };
  143.  
  144. enum {
  145.         uppSoundComponentPlaySourceBufferProcInfo = kPascalStackBased
  146.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  147.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  148.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundSource)))
  149.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(SoundParamBlockPtr)))
  150.                 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
  151. };
  152.  
  153. // this macro will create a global structure of type RoutineDescriptor
  154.  
  155. #define DeclareRoutineDescriptor(info, proc)                                    \
  156.     RoutineDescriptor g##proc##RD = BUILD_ROUTINE_DESCRIPTOR(info, proc)
  157.  
  158. #define GetComponentFunction(proc)    (&g##proc##RD)
  159.  
  160. DeclareRoutineDescriptor(uppSoundComponentRegisterProcInfo, __SoundComponentRegister);
  161. DeclareRoutineDescriptor(uppSoundComponentCloseProcInfo, __SoundComponentClose);
  162. DeclareRoutineDescriptor(uppSoundComponentOpenProcInfo, __SoundComponentOpen);
  163. DeclareRoutineDescriptor(uppSoundComponentSetSourceProcInfo, __SoundComponentSetSource);
  164. DeclareRoutineDescriptor(uppSoundComponentGetSourceProcInfo, __SoundComponentGetSource);
  165. DeclareRoutineDescriptor(uppSoundComponentGetSourceDataProcInfo, __SoundComponentGetSourceData);
  166. DeclareRoutineDescriptor(uppSoundComponentSetOutputProcInfo, __SoundComponentSetOutput);
  167. DeclareRoutineDescriptor(uppSoundComponentGetInfoProcInfo, __SoundComponentGetInfo);
  168. DeclareRoutineDescriptor(uppSoundComponentStopSourceProcInfo, __SoundComponentStopSource);
  169. DeclareRoutineDescriptor(uppSoundComponentPlaySourceBufferProcInfo, __SoundComponentPlaySourceBuffer);
  170.  
  171.  
  172. #else //GENERATING68K
  173.  
  174. #define GetComponentFunction(proc)    (ComponentFunctionUPP)(proc)
  175.  
  176. #endif
  177.  
  178. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  179. //    Sound Component Entry Point
  180. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  181.  
  182. // in 68k (non-CFM) the entry point is defined to be the SoundComponentEntryPoint
  183. // in PowerPC the entry point is a Routine Descriptor pointing to SoundComponentEntryPoint
  184.  
  185. //pascal ComponentResult SoundComponentDispatcher(ComponentParameters *params, SoundComponentGlobalsPtr globals);
  186.  
  187. #if !GENERATINGCFM
  188. #define SoundComponentDispatcher SoundComponentEntryPoint
  189. #else
  190. pascal ComponentResult SoundComponentDispatcher(ComponentParameters *params, SoundComponentGlobalsPtr globals);
  191. RoutineDescriptor SoundComponentEntryPoint = BUILD_ROUTINE_DESCRIPTOR(uppSoundComponentEntryPointProcInfo, SoundComponentDispatcher);
  192. #endif
  193.  
  194. pascal ComponentResult SoundComponentDispatcher(ComponentParameters *params, SoundComponentGlobalsPtr globals)
  195. {
  196.     ComponentResult                result;
  197.     short                        selector = params->what;
  198.  
  199.     if (selector < 0)
  200.         switch (selector - kComponentRegisterSelect)    // standard component selectors
  201.         {
  202.             case kComponentRegisterSelect - kComponentRegisterSelect:
  203.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentRegister));
  204.                 break;
  205.  
  206.             case kComponentVersionSelect - kComponentRegisterSelect:
  207.                 return (kSoundComponentVersion);
  208.                 break;
  209.  
  210.             case kComponentCanDoSelect - kComponentRegisterSelect:
  211.                 result = __SoundComponentCanDo(0, *((short *) ¶ms->params[0]));
  212.                 break;
  213.  
  214.             case kComponentCloseSelect - kComponentRegisterSelect:
  215.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentClose));
  216.                 break;
  217.  
  218.             case kComponentOpenSelect - kComponentRegisterSelect:
  219.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentOpen));
  220.                 break;
  221.  
  222.             default:
  223.                 result = badComponentSelector;
  224.                 break;
  225.         }
  226.     else if (selector < kDelegatedSoundComponentSelectors)            // selectors that cannot be delegated
  227.         switch (selector)
  228.         {
  229.             case kSoundComponentSetSourceSelect:
  230.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentSetSource));
  231.                 break;
  232.  
  233.             case kSoundComponentGetSourceSelect:
  234.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentGetSource));
  235.                 break;
  236.  
  237.             case kSoundComponentGetSourceDataSelect:
  238.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentGetSourceData));
  239.                 break;
  240.  
  241.             case kSoundComponentSetOutputSelect:
  242.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentSetOutput));
  243.                 break;
  244.  
  245.             default:
  246.                 result = badComponentSelector;
  247.                 break;
  248.         }
  249.     else                                                    // selectors that can be delegated
  250.         switch (selector)
  251.         {
  252.             case kSoundComponentGetInfoSelect:
  253.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentGetInfo));
  254.                 break;
  255.  
  256.             case kSoundComponentStopSourceSelect:
  257.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentStopSource));
  258.                 break;
  259.  
  260.             case kSoundComponentPlaySourceBufferSelect:
  261.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentPlaySourceBuffer));
  262.                 break;
  263.  
  264.             default:
  265.                 result = DelegateComponentCall(params, globals->sourceComponent);
  266.                 break;
  267.         }
  268.  
  269.     return (result);
  270. }
  271.  
  272.  
  273. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  274. static pascal ComponentResult __SoundComponentCanDo(void *unused1, short selector)
  275. {
  276. #pragma unused (unused1)
  277.  
  278.     ComponentResult        result;
  279.  
  280.     switch (selector)
  281.     {
  282.         case kComponentRegisterSelect:
  283.         case kComponentVersionSelect:
  284.         case kComponentCanDoSelect:
  285.         case kComponentCloseSelect:
  286.         case kComponentOpenSelect:
  287.         case kSoundComponentSetSourceSelect:
  288.         case kSoundComponentGetSourceSelect:
  289.         case kSoundComponentGetSourceDataSelect:
  290.         case kSoundComponentSetOutputSelect:
  291.         // selectors that can be delegated
  292.         case kSoundComponentGetInfoSelect:
  293.         case kSoundComponentStopSourceSelect:
  294.         case kSoundComponentPlaySourceBufferSelect:
  295.             result = true;
  296.             break;
  297.  
  298.         default:
  299.             result = false;
  300.             break;
  301.     }
  302.  
  303.     return (result);
  304. }
  305.  
  306.